﻿using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using SharePointHarvester;
using SharePointHarvester.Events;

namespace WorkflowDiscoveryApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("A test to determine what workflows exist in SP libraries..");
            var siteName = string.Empty;

            var run = new Runner();

            if (args.Length == 0) 
            {
                Console.WriteLine("Please enter a sharepoint site name EG http://sharepoint.com");
                siteName = Console.ReadLine();
            }
            else
            {
                run.CheckWorkflow(args[0]);
            }

            if (!string.IsNullOrEmpty(siteName))
                run.CheckWorkflow(siteName.Trim());

            Console.WriteLine();
            Console.WriteLine("Custom Workflow summary");
            Console.ForegroundColor = ConsoleColor.Green;
            foreach (string wf in Runner.customWorkflowNames)
            {
                Console.WriteLine(wf);
            }

            Console.WriteLine();
            Console.ResetColor();
            Console.WriteLine("Internal Workflow summary");
            Console.ForegroundColor = ConsoleColor.Green;
            foreach (string wf in Runner.internalWorkflowNames)
            {
                Console.WriteLine(wf);
            }
            Console.ResetColor();
            Console.WriteLine();
            Console.WriteLine(string.Format("Number of custom Workflows: {0}", Runner.customWorkflow));
            Console.WriteLine(string.Format("Number of internal Workflows: {0}", Runner.internalWorkflow));
            Console.WriteLine();
            Console.WriteLine("Press any key to exit.. ");
            Console.ReadLine();
        }
    }

    internal class Runner
    {
        public static int customWorkflow;
        public static int internalWorkflow;
        public static List<string> internalWorkflowNames = new List<string>();
        public static List<string> customWorkflowNames = new List<string>();

        public void CheckWorkflow(string url)
        {
            try
            {
                var siteHarvester = new SiteHarvester
                {
                    Url = url, // site URL
                    Recursive = true // search child sites
                };

                // Raises an event everytime a Library is hit and calls siteHarvestor_ListFound
                siteHarvester.ListFound += siteHarvestor_ListFound;
                siteHarvester.RunHarvester();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error workflow: " + ex.Message);
            }
        }

        private void siteHarvestor_ListFound(object sender, ListFoundEventArg e)
        {
            Console.WriteLine();
            Console.WriteLine("Checking: " + e._list.Title);
            try
            {
                // WF associated with a list
                foreach (SPWorkflowAssociation wfAssoc in e._list.WorkflowAssociations)
                {
                    try
                    {
                        // custom WF checking
                        if (wfAssoc.BaseTemplate == null && wfAssoc.InternalName.Contains("Xoml"))
                        {
                            // add to collection if not already there
                            if (!customWorkflowNames.Contains(wfAssoc.Name))
                            {
                                Console.WriteLine("Custom: " + wfAssoc.Name);
                                customWorkflowNames.Add(wfAssoc.Name + " - " + e._list.RootFolder.ServerRelativeUrl);
                                customWorkflow++;
                            }
                        }
                        else
                        {
                            if (!internalWorkflowNames.Contains(wfAssoc.Name))
                            {
                                Console.WriteLine("Internal: " + wfAssoc.Name);
                                internalWorkflowNames.Add(wfAssoc.Name + " - " + e._list.RootFolder.ServerRelativeUrl);
                                internalWorkflow++;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error loop: " + ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error list: " + ex.Message);
            }
        }
    }
}